package br.com.jk.financeiro.movimento;

import br.com.jk.cliente.Cliente;
import br.com.jk.financeiro.contaBanco.*;
import br.com.jk.financeiro.movimentotipo.MovimentoTipo;
import br.com.jk.fornecedor.Fornecedor;
import br.com.jk.util.StatusType.Status;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;

/**
 *
 * @author camilo
 */
@Entity
@Table(name = MovimentoDao.NAME_TABLE, schema = MovimentoDao.NAME_SCHEMA, uniqueConstraints = {
  @UniqueConstraint(name = MovimentoDao.NAME_UK_NUMERO_CHEQUE,
          columnNames = {MovimentoDao.NAME_COLUMN_CONTABANCO, MovimentoDao.NAME_COLUMN_NUMERO_CHEQUE})
}, indexes = {
  @Index(columnList = MovimentoDao.NAME_COLUMN_NUMERO_CHEQUE, name = "in_numero_cheque"),
  @Index(columnList = MovimentoDao.NAME_COLUMN_DATA_PREVISAO, name = "in_data_previsao"),
  @Index(columnList = MovimentoDao.NAME_COLUMN_DATA_REALIZADO, name = "in_data_realizado"),
  @Index(columnList = MovimentoDao.NAME_COLUMN_NUM_DOCUMENTO, name = "in_num_documento"),
  @Index(columnList = MovimentoDao.NAME_COLUMN_FORNECEDOR, name = "in_fornecedor"),
  @Index(columnList = MovimentoDao.NAME_COLUMN_CLIENTE, name = "in_cliente"),
  @Index(columnList = MovimentoDao.NAME_COLUMN_CONTABANCO, name = "in_conta_banco")
})
public class Movimento implements Serializable {

  public static final String ATTRIBUTE_ID = "id";
  public static final String ATTRIBUTE_NUMERO_CHEQUE = "numero";
  public static final String ATTRIBUTE_VALOR = "valor";
  public static final String ATTRIBUTE_DATA_LANCAMENTO = "dataLancamento";
  public static final String ATTRIBUTE_DATA_PREVISAO = "dataPrevisao";
  public static final String ATTRIBUTE_DATA_REALIZADO = "dataRealizado";
  public static final String ATTRIBUTE_STATUS = "status";
  public static final String ATTRIBUTE_OBSERVACAO = "observacao";
  public static final String ATTRIBUTE_NUM_DOCUMENTO = "numDocumento";
  public static final String ATTRIBUTE_CLIENTE = "cliente";
  public static final String ATTRIBUTE_FORNECEDOR = "fornecedor";
  public static final String ATTRIBUTE_CONTA_BANCO = "contaBanco";
  public static final String ATTRIBUTE_MOVIMENTO_TIPO = "movimentoTipo";
  @Id
  @SequenceGenerator(name = MovimentoDao.NAME_SEQUENCE, sequenceName = MovimentoDao.NAME_SEQUENCE,
          schema = MovimentoDao.NAME_SCHEMA)
  @GeneratedValue(strategy = GenerationType.AUTO, generator = MovimentoDao.NAME_SEQUENCE)
  private int id;
  @Column(name = MovimentoDao.NAME_COLUMN_NUMERO_CHEQUE)
  private Integer numeroCheque;
  @Column(name = MovimentoDao.NAME_COLUMN_VALOR, nullable = false)
  private BigDecimal valor;
  @Temporal(TemporalType.DATE)
  @Column(name = MovimentoDao.NAME_COLUMN_DATA_LANCAMENTO, updatable = false)
  private Date dataLancamento;
  @Temporal(TemporalType.DATE)
  @Column(name = MovimentoDao.NAME_COLUMN_DATA_PREVISAO)
  private Date dataPrevisao;
  @Temporal(TemporalType.DATE)
  @Column(name = MovimentoDao.NAME_COLUMN_DATA_REALIZADO)
  private Date dataRealizado;
  @Column(nullable = false, name = MovimentoDao.NAME_COLUMN_STATUS)
  private Status status;
  @Column(name = MovimentoDao.NAME_COLUMN_OBSERVACAO)
  private String observacao;
  @Column(name = MovimentoDao.NAME_COLUMN_NUM_DOCUMENTO)
  private Integer numDocumento;
  @ManyToOne
  @JoinColumn(name = MovimentoDao.NAME_COLUMN_MOVIMENTO_TIPO, nullable = false,
          foreignKey = @ForeignKey(name = MovimentoDao.NAME_FK_MOVIMENTO_TIPO))
  private MovimentoTipo movimentoTipo;
  @ManyToOne
  @JoinColumn(name = MovimentoDao.NAME_COLUMN_CLIENTE,
          foreignKey = @ForeignKey(name = MovimentoDao.NAME_FK_CLIENTE))
  private Cliente cliente;
  @ManyToOne
  @JoinColumn(name = MovimentoDao.NAME_COLUMN_FORNECEDOR,
          foreignKey = @ForeignKey(name = MovimentoDao.NAME_FK_FORNECEDOR))
  private Fornecedor fornecedor;
  @ManyToOne
  @JoinColumn(name = MovimentoDao.NAME_COLUMN_CONTABANCO, nullable = false,
          foreignKey = @ForeignKey(name = MovimentoDao.NAME_FK_CONTABANCO))
  private ContaBanco contaBanco;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public Integer getNumeroCheque() {
    return numeroCheque;
  }

  public void setNumeroCheque(Integer numeroCheque) {
    this.numeroCheque = numeroCheque;
  }

  public BigDecimal getValor() {
    return valor;
  }

  public void setValor(BigDecimal valor) {
    this.valor = valor;
  }

  public Date getDataLancamento() {
    return dataLancamento;
  }

  public void setDataLancamento(Date dataLancamento) {
    this.dataLancamento = dataLancamento;
  }

  public Date getDataPrevisao() {
    return dataPrevisao;
  }

  public void setDataPrevisao(Date dataPrevisao) {
    this.dataPrevisao = dataPrevisao;
  }

  public Date getDataRealizado() {
    return dataRealizado;
  }

  public void setDataRealizado(Date dataRealizado) {
    this.dataRealizado = dataRealizado;
  }

  public Status getStatus() {
    return status;
  }

  public void setStatus(Status status) {
    this.status = status;
  }

  public String getObservacao() {
    return observacao;
  }

  public void setObservacao(String observacao) {
    this.observacao = observacao;
  }

  public Integer getNumDocumento() {
    return numDocumento;
  }

  public void setNumDocumento(Integer numDocumento) {
    this.numDocumento = numDocumento;
  }

  public MovimentoTipo getMovimentoTipo() {
    return movimentoTipo;
  }

  public void setMovimentoTipo(MovimentoTipo movimentoTipo) {
    this.movimentoTipo = movimentoTipo;
  }

  public Cliente getCliente() {
    return cliente;
  }

  public void setCliente(Cliente cliente) {
    this.cliente = cliente;
  }

  public Fornecedor getFornecedor() {
    return fornecedor;
  }

  public void setFornecedor(Fornecedor fornecedor) {
    this.fornecedor = fornecedor;
  }

  public ContaBanco getContaBanco() {
    return contaBanco;
  }

  public void setContaBanco(ContaBanco contaBanco) {
    this.contaBanco = contaBanco;
  }

  @Override
  public int hashCode() {
    int hash = 7;
    hash = 53 * hash + this.id;
    hash = 53 * hash + Objects.hashCode(this.numeroCheque);
    hash = 53 * hash + Objects.hashCode(this.valor);
    hash = 53 * hash + Objects.hashCode(this.dataLancamento);
    hash = 53 * hash + Objects.hashCode(this.dataPrevisao);
    hash = 53 * hash + Objects.hashCode(this.dataRealizado);
    hash = 53 * hash + Objects.hashCode(this.status);
    hash = 53 * hash + Objects.hashCode(this.observacao);
    hash = 53 * hash + Objects.hashCode(this.numDocumento);
    hash = 53 * hash + Objects.hashCode(this.movimentoTipo);
    hash = 53 * hash + Objects.hashCode(this.cliente);
    hash = 53 * hash + Objects.hashCode(this.fornecedor);
    hash = 53 * hash + Objects.hashCode(this.contaBanco);
    return hash;
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final Movimento other = (Movimento) obj;
    if (this.id != other.id) {
      return false;
    }
    if (!Objects.equals(this.numeroCheque, other.numeroCheque)) {
      return false;
    }
    if (!Objects.equals(this.valor, other.valor)) {
      return false;
    }
    if (!Objects.equals(this.dataLancamento, other.dataLancamento)) {
      return false;
    }
    if (!Objects.equals(this.dataPrevisao, other.dataPrevisao)) {
      return false;
    }
    if (!Objects.equals(this.dataRealizado, other.dataRealizado)) {
      return false;
    }
    if (this.status != other.status) {
      return false;
    }
    if (!Objects.equals(this.observacao, other.observacao)) {
      return false;
    }
    if (!Objects.equals(this.numDocumento, other.numDocumento)) {
      return false;
    }
    if (!Objects.equals(this.movimentoTipo, other.movimentoTipo)) {
      return false;
    }
    if (!Objects.equals(this.cliente, other.cliente)) {
      return false;
    }
    if (!Objects.equals(this.fornecedor, other.fornecedor)) {
      return false;
    }
    return Objects.equals(this.contaBanco, other.contaBanco);
  }
}
